home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Pascal / System / HDGarbageCollector / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-05  |  51.2 KB  |  2,448 lines  |  [TEXT/KAHL]

  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4.  
  5. #undef _TEST
  6. /*#define _TEST*/
  7.  
  8.  
  9. #define ERRORDLOG            256
  10. #define INFODLOG            257
  11. #define CRQDLOG                258
  12. #define CRDQDLOG            259
  13. #define HELPWIND            128
  14. #define HELPTEXT            128
  15. #define HELPSTYL            128
  16. #define MAPFILENAME            "HD Dirs List"
  17. #define FILELISTNAME        "HD File List"
  18. #define CREATOR                'Gbge'
  19. #define STUDENTDIRECTORY    "Student Work"
  20.  
  21. #define EQSTR            0
  22.  
  23.  
  24.  
  25. typedef  struct myVolumeInfoBlock
  26. {
  27. char        name[32];
  28. int            attrib;
  29. char        finderInfo[32];
  30. };
  31.  
  32. #define VolumeInfo    struct myVolumeInfoBlock
  33.  
  34.  
  35. typedef struct myDirInfoBlock
  36. {
  37. char        name[32];
  38. int            attrib;
  39. long        dirID;
  40. long        parentDirID;
  41. char        finderInfo[32];
  42. };
  43.  
  44. #define DirInfo    struct myDirInfoBlock
  45.  
  46.  
  47. typedef struct myFileInfoBlock
  48. {
  49. char    name[32];
  50. int        attrib;
  51. long    creator;
  52. long    type;
  53. long    creationDate;
  54. long    parentDirID;
  55. char    finderInfo[32];
  56. };
  57.  
  58. #define FileInfo    struct myFileInfoBlock
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65. static CInfoPBRec    myCPB;
  66. static int            vRefNum;
  67. static char            errorString[512];
  68. static char            currentDirName[512];
  69. static DialogPtr    theDPtr = 0L;
  70. static long            numDirs = 0L,numFiles = 0L;
  71. static VolumeInfo    theVolInfo;
  72. static DirInfo        theDirInfo,*listOfDirs = 0L;
  73. static FileInfo        theFileInfo,*listOfFiles = 0L;
  74. static long            studentWorkDirID = 0L;
  75. static int            sysFolderVRefNum = 0;
  76.  
  77.  
  78. int main(void);
  79. static void    OpenInfoWindow(void);
  80. static void    SetInfoMessage(char *theMessage);
  81. static void    CloseInfoWindow(void);
  82. static int    InfoBreak(void);
  83. static int SetupVolRefNum(void);
  84. static void RestartProc(void);
  85. static int MapVolume(void);
  86. static int  ListDirectory(int dirsFRefNum,int filesFRefNum,long theIODirID);
  87. static void CenterWindow(WindowPtr wPtr);
  88. static pascal void HiliteDefaultButton(DialogPtr theDPtr,int whichItem);
  89. static void ErrorAlert(char *p0);
  90. static int CreateRestoreQuit(char *thePrompt,int theDefault);
  91. static int ContinueRenameDeleteQuit(char *thePrompt,int theDefault);
  92. static int LoadAndParseFiles(void);
  93. static void DisposeFileList(void);
  94. static int LoadAndParseDirs(void);
  95. static void DisposeDirList(void);
  96. static int OptionKey(void);
  97. static int CompareFiles(FileInfo *first,FileInfo *second);
  98. static int    SortFileList(void);
  99. static long FindFile(FileInfo *theFileInfo);
  100. static int CompareDirs(DirInfo *first,DirInfo *second);
  101. static int    SortDirList(void);
  102. static long FindDir(DirInfo *theDirInfo);
  103. static int ResetVolumeAndDirs(void);
  104. static int ResetFilesAndCollectGarbage(void);
  105. static int  ProcessDirectory(long theIODirID);
  106. static void DoHelpBox(int helpResWIND,int helpResTEXT,int helpResSTYL);
  107. static pascal void HelpScrollProc(ControlHandle theControl,int theCode);
  108.  
  109.  
  110.  
  111.  
  112. int main(void)
  113. {
  114. int        userChoice,errCode;
  115. char    tempString[256];
  116.  
  117.  
  118.     InitGraf(&thePort);
  119.     InitFonts();
  120.     FlushEvents(everyEvent,0);
  121.     InitWindows();
  122.     InitMenus();
  123.     TEInit();
  124.     InitDialogs(RestartProc);
  125.     InitCursor();
  126.     MoreMasters();
  127.     
  128.     
  129.     DoHelpBox(HELPWIND,HELPTEXT,HELPSTYL);
  130.     
  131.     if ((errCode = SetupVolRefNum()) != noErr)
  132.         return(errCode);
  133.     
  134.     
  135.     strcpy(tempString,":");
  136.     strcat(tempString,STUDENTDIRECTORY);
  137.     strcat(tempString,":");
  138.     CtoPstr(tempString);
  139.     
  140.     myCPB.dirInfo.ioCompletion = 0L;
  141.     myCPB.dirInfo.ioNamePtr = (StringPtr) &tempString;
  142.     myCPB.dirInfo.ioVRefNum = vRefNum;
  143.     myCPB.dirInfo.ioFDirIndex = 0;
  144.     myCPB.dirInfo.ioDrDirID = 0L;
  145.     
  146.     errCode = PBGetCatInfo(&myCPB,FALSE);
  147.     
  148.     if (errCode != noErr && errCode != fnfErr)
  149.     {
  150.         errCode = createFolder(STUDENTDIRECTORY);
  151.         
  152.         if (errCode != noErr)
  153.             return(errCode);
  154.     }
  155.     
  156.     studentWorkDirID = myCPB.dirInfo.ioDrDirID;
  157.     
  158.     
  159.     do
  160.     {
  161.         userChoice = CreateRestoreQuit("Create volume map or Restore volume info?",2);
  162.         
  163.         if (userChoice == 1)
  164.             MapVolume();
  165.         
  166.         else if (userChoice == 2)
  167.         {
  168.             ResetVolumeAndDirs();
  169.             ResetFilesAndCollectGarbage();
  170.         }
  171.         
  172.         DisposeFileList();
  173.         DisposeDirList();
  174.         
  175.         CloseInfoWindow();
  176.         
  177.         FlushEvents(everyEvent,0);
  178.         
  179.     } while (userChoice != 3);
  180. }
  181.  
  182.  
  183.  
  184.  
  185.  
  186. static void    OpenInfoWindow(void)
  187. {
  188. int                itemHit;
  189. EventRecord        theEvent;
  190. DialogPtr        tempDPtr;
  191. GrafPtr            oldPort;
  192.  
  193.     GetPort(&oldPort);
  194.  
  195.     theDPtr = GetNewDialog(INFODLOG, 0L,(WindowPtr) -1L);
  196.     
  197.     if (!theDPtr)
  198.     {
  199.         ErrorAlert("Can't get INFODLOG resource!");
  200.         ExitToShell();
  201.     }
  202.     
  203.     SetPort(theDPtr);
  204.     
  205.     CenterWindow(theDPtr);
  206.     ShowWindow(theDPtr);
  207.     
  208.     while (!GetNextEvent(updateMask,&theEvent) || theEvent.message != (long) theDPtr);
  209.     
  210.     DialogSelect(&theEvent,&tempDPtr,&itemHit);
  211.     
  212.     SetPort(oldPort);
  213. }
  214.  
  215.  
  216.  
  217.  
  218. static void    SetInfoMessage(char *theMessage)
  219. {
  220. int                itemHit,type,oldFont,oldSize;
  221. Handle            theItem;
  222. Rect            theRect;
  223. char            tempString[256];
  224. GrafPtr            oldPort;
  225. RgnHandle        theRgn;
  226.  
  227.     if (!theDPtr)
  228.         OpenInfoWindow();
  229.     
  230.     GetPort(&oldPort);
  231.     SetPort(theDPtr);
  232.     
  233.     oldFont = theDPtr->txFont;
  234.     oldSize = theDPtr->txSize;
  235.     
  236.     strcpy(tempString,theMessage);
  237.     CtoPstr(tempString);
  238.     GetDItem(theDPtr,2,&type,&theItem,&theRect);
  239.     
  240.     InsetRect(&theRect,-2,-2);
  241.     FrameRect(&theRect);
  242.     InsetRect(&theRect,2,2);
  243.     
  244.     theRgn = NewRgn();
  245.     ScrollRect(&theRect,0,-12,theRgn);
  246.     DisposeRgn(theRgn);
  247.     ClipRect(&theRect);
  248.     MoveTo(theRect.left + 3,theRect.bottom - 3);
  249.     
  250.     TextFont(geneva);
  251.     TextSize(10);
  252.     DrawString(tempString);
  253.     
  254.     
  255.     SetRect(&theRect,-32768,-32768,32767,32767);
  256.     ClipRect(&theRect);
  257.     
  258.     TextFont(oldFont);
  259.     TextSize(oldSize);
  260.     SetPort(oldPort);
  261.     
  262.     if (OptionKey())
  263.     {
  264.         while (!Button());
  265.         while (Button());
  266.     }
  267. }
  268.  
  269.  
  270.  
  271. static void    CloseInfoWindow(void)
  272. {
  273.     if (theDPtr)
  274.         DisposDialog(theDPtr);
  275.     
  276.     theDPtr = 0L;
  277. }
  278.  
  279.  
  280.  
  281.  
  282. static int    InfoBreak(void)
  283. {
  284. int                itemHit, type;
  285. Handle            theItem;
  286. Rect            theRect;
  287. EventRecord        theEvent;
  288. DialogPtr        tempDPtr;
  289.  
  290.  
  291.     itemHit = 0;
  292.     
  293.     if (GetNextEvent(everyEvent,&theEvent))
  294.     {
  295.         if (!IsDialogEvent(&theEvent) || !DialogSelect(&theEvent,&tempDPtr,&itemHit) || tempDPtr!=theDPtr)
  296.             itemHit = 0;
  297.     }
  298.     
  299.     if (itemHit == 1)
  300.         return(TRUE);
  301.     else
  302.         return(FALSE);
  303. }
  304.  
  305.  
  306.  
  307.  
  308.  
  309. static int SetupVolRefNum(void)
  310. {
  311. long        freeBytes;
  312. int            errCode;
  313. char        volName[256];
  314. SysEnvRec    theWorld;
  315.  
  316.  
  317. #ifndef _TEST
  318.  
  319.     if ((errCode = GetVInfo(0,volName,&vRefNum,&freeBytes)) != noErr)
  320.     {
  321.         sprintf(errorString,"SetupVolRefNum:\rGetVInfo() error %d",errCode);
  322.         ErrorAlert(errorString);
  323.         return(errCode);
  324.     }
  325.  
  326. #else
  327.     
  328.     if ((errCode = GetVol(volName,&vRefNum)) != noErr)
  329.     {
  330.         sprintf(errorString,"SetupVolRefNum:\rGetVol() error %d",errCode);
  331.         ErrorAlert(errorString);
  332.         return(errCode);
  333.     }
  334.  
  335. #endif
  336.  
  337.     if ((errCode = SysEnvirons(1,&theWorld)) != noErr)
  338.     {
  339.         sprintf(errorString,"SetupVolRefNum:\rSysEnvirons() error %d",errCode);
  340.         ErrorAlert(errorString);
  341.         return(errCode);
  342.     }
  343.     
  344.     sysFolderVRefNum = theWorld.sysVRefNum;
  345.     
  346.     return(noErr);
  347. }
  348.  
  349.  
  350.  
  351. static void RestartProc(void)
  352. {
  353.     ExitToShell();
  354. }
  355.  
  356.  
  357.  
  358. static int MapVolume(void)
  359. {
  360. int                errCode,j;
  361. int                dirsFRefNum,filesFRefNum;
  362. long            freeBytes,byteCount;
  363. char            tempString[256],dirsFName[256],filesFName[256];
  364. HParamBlockRec    myHPB;
  365.  
  366.  
  367.     errCode = SetupVolRefNum();
  368.     
  369.     if (errCode != noErr)
  370.         return(errCode);
  371.     
  372.     
  373.     strcpy(filesFName,FILELISTNAME);
  374.     CtoPstr(filesFName);
  375.     
  376.     errCode = FSOpen(filesFName,sysFolderVRefNum,&filesFRefNum);
  377.         
  378.     if (errCode!=noErr && errCode!=fnfErr)
  379.     {
  380.         sprintf(errorString,"MapVolume:\rFSOpen('%s') error %d",FILELISTNAME,errCode);
  381.         ErrorAlert(errorString);
  382.         return(errCode);
  383.     }
  384.     
  385.     else if (errCode==fnfErr)
  386.     {
  387.         if ((errCode = Create(filesFName,sysFolderVRefNum,CREATOR,'Stuf'))!=noErr)
  388.         {
  389.             sprintf(errorString,"MapVolume:\rCreate('%s') error %d",FILELISTNAME,errCode);
  390.             ErrorAlert(errorString);
  391.             return(errCode);
  392.         }
  393.         
  394.         else if ((errCode=FSOpen(filesFName,sysFolderVRefNum,&filesFRefNum))!=noErr)
  395.         {
  396.             sprintf(errorString,"MapVolume:\rFSOpen('%s') error %d",FILELISTNAME,errCode);
  397.             ErrorAlert(errorString);
  398.             return(errCode);
  399.         }
  400.     }
  401.     
  402.     if ((errCode = SetEOF(filesFRefNum,0L))!=noErr)
  403.     {
  404.         sprintf(errorString,"MapVolume:\rSetEOF('%s') error %d",FILELISTNAME,errCode);
  405.         ErrorAlert(errorString);
  406.         FSClose(filesFRefNum);
  407.         return(errCode);
  408.     }
  409.     
  410.     
  411.     strcpy(dirsFName,MAPFILENAME);
  412.     CtoPstr(dirsFName);
  413.     
  414.     errCode = FSOpen(dirsFName,sysFolderVRefNum,&dirsFRefNum);
  415.         
  416.     if (errCode!=noErr && errCode!=fnfErr)
  417.     {
  418.         sprintf(errorString,"MapVolume:\rFSOpen('%s') error %d",MAPFILENAME,errCode);
  419.         ErrorAlert(errorString);
  420.         FSClose(filesFRefNum);
  421.         return(errCode);
  422.     }
  423.     
  424.     else if (errCode==fnfErr)
  425.     {
  426.         if ((errCode = Create(dirsFName,sysFolderVRefNum,CREATOR,'Stuf'))!=noErr)
  427.         {
  428.             sprintf(errorString,"MapVolume:\rCreate('%s') error %d",MAPFILENAME,errCode);
  429.             ErrorAlert(errorString);
  430.             FSClose(filesFRefNum);
  431.             return(errCode);
  432.         }
  433.         
  434.         else if ((errCode=FSOpen(dirsFName,sysFolderVRefNum,&dirsFRefNum))!=noErr)
  435.         {
  436.             sprintf(errorString,"MapVolume:\rFSOpen('%s') error %d",MAPFILENAME,errCode);
  437.             ErrorAlert(errorString);
  438.             FSClose(filesFRefNum);
  439.             return(errCode);
  440.         }
  441.     }
  442.     
  443.     if ((errCode = SetEOF(dirsFRefNum,0L))!=noErr)
  444.     {
  445.         sprintf(errorString,"MapVolume:\rSetEOF('%s') error %d",MAPFILENAME,errCode);
  446.         ErrorAlert(errorString);
  447.         FSClose(dirsFRefNum);
  448.         FSClose(filesFRefNum);
  449.         return(errCode);
  450.     }
  451.     
  452.     myHPB.volumeParam.ioCompletion = 0L;
  453.     myHPB.volumeParam.ioNamePtr = (StringPtr) &(theVolInfo.name);
  454.     myHPB.volumeParam.ioVRefNum = 0;
  455.     myHPB.volumeParam.ioVolIndex = -1;
  456.     
  457.     errCode = PBHGetVInfo(&myHPB,FALSE);
  458.     
  459.     if (errCode != noErr)
  460.     {
  461.         sprintf(errorString,"MapVolume:\rPBHGetVInfo() error %d",errCode);
  462.         ErrorAlert(errorString);
  463.         FSClose(dirsFRefNum);
  464.         FSClose(filesFRefNum);
  465.         return(errCode);
  466.     }
  467.     
  468.     
  469.     PtoCstr(theVolInfo.name);
  470.     strcpy(currentDirName,theVolInfo.name);
  471.     
  472.     theVolInfo.attrib = myHPB.volumeParam.ioVAtrb;
  473.     
  474.     for (j=0;j<32;j++)
  475.         theVolInfo.finderInfo[j] = ((char *) &(myHPB.volumeParam.ioVFndrInfo))[j];
  476.         
  477.     byteCount = sizeof(VolumeInfo);
  478.     
  479.     if ((errCode = FSWrite(dirsFRefNum,&byteCount,&theVolInfo))!=noErr)
  480.     {
  481.         sprintf(errorString,"MapVolume:\rFSWrite error %d",errCode);
  482.         ErrorAlert(errorString);
  483.         FSClose(dirsFRefNum);
  484.         FSClose(filesFRefNum);
  485.         dirsFRefNum = 0;
  486.         return(errCode);
  487.     }
  488.     
  489.     errCode = ListDirectory(dirsFRefNum,filesFRefNum,0L);
  490.     
  491.     FSClose(dirsFRefNum);
  492.     FSClose(filesFRefNum);
  493.     
  494.     if (errCode == noErr)
  495.     {
  496.         SortFileList();
  497.         SortDirList();
  498.     }
  499.     
  500.     FlushVol("\p",vRefNum);
  501.     FlushVol("\p",sysFolderVRefNum);
  502.     
  503.     return(noErr);
  504. }
  505.  
  506.  
  507.  
  508.  
  509.  
  510. static int  ListDirectory(int dirsFRefNum,int filesFRefNum,long theIODirID)
  511. {
  512. int        index,errCode,j;
  513. long    byteCount;
  514. char    tempString[256];
  515.  
  516.     if (InfoBreak())
  517.         return(-1);
  518.     
  519.     index = 1;
  520.         
  521.     do
  522.     {
  523.         tempString[0] = 0;
  524.         
  525.         myCPB.hFileInfo.ioCompletion = 0L;
  526.         myCPB.hFileInfo.ioNamePtr = (StringPtr) &tempString;
  527.         myCPB.hFileInfo.ioVRefNum = vRefNum;
  528.         myCPB.hFileInfo.ioFDirIndex = index++;
  529.         myCPB.hFileInfo.ioDirID = theIODirID;
  530.         
  531.         errCode = PBGetCatInfo(&myCPB,FALSE);
  532.         
  533.         if (errCode!=noErr && errCode!=fnfErr)
  534.         {
  535.             sprintf(errorString,"ListDirectory:\rPBGetCatInfo error %d",errCode);
  536.             ErrorAlert(errorString);
  537.             return(errCode);
  538.         }
  539.         
  540.         else if (errCode == noErr)
  541.         {
  542.             PtoCstr(tempString);
  543.             
  544.             strcpy(errorString,currentDirName);
  545.             strcat(errorString,":");
  546.             strcat(errorString,tempString);
  547.             SetInfoMessage(errorString);
  548.             
  549.             if (myCPB.hFileInfo.ioFlAttrib & 0x10) /* is a folder */
  550.             {
  551.                 strcpy(theDirInfo.name,tempString);
  552.                 theDirInfo.dirID = myCPB.dirInfo.ioDrDirID;
  553.                 theDirInfo.parentDirID = myCPB.dirInfo.ioDrParID;
  554.                 theDirInfo.attrib = myCPB.dirInfo.ioFlAttrib;
  555.                 
  556.                 for (j=0;j<16;j++)
  557.                     theDirInfo.finderInfo[j] = ((char *) &(myCPB.dirInfo.ioDrUsrWds))[j];
  558.                 
  559.                 for (j=0;j<16;j++)
  560.                     theDirInfo.finderInfo[j + 16] = ((char *) &(myCPB.dirInfo.ioDrFndrInfo))[j];
  561.                     
  562.                 byteCount = sizeof(DirInfo);
  563.                 
  564.                 if ((errCode = FSWrite(dirsFRefNum,&byteCount,&theDirInfo))!=noErr)
  565.                 {
  566.                     sprintf(errorString,"ListDirectory:\rFSWrite(%s) error %d",MAPFILENAME,errCode);
  567.                     ErrorAlert(errorString);
  568.                     return(errCode);
  569.                 }
  570.             }
  571.             
  572.             else
  573.             {
  574.                 theFileInfo.type = myCPB.hFileInfo.ioFlFndrInfo.fdType;
  575.                 theFileInfo.creator = myCPB.hFileInfo.ioFlFndrInfo.fdCreator;
  576.                 theFileInfo.creationDate = myCPB.hFileInfo.ioFlCrDat;
  577.                 theFileInfo.parentDirID = myCPB.hFileInfo.ioFlParID;
  578.                 theFileInfo.attrib = myCPB.hFileInfo.ioFlAttrib;
  579.                 strcpy(theFileInfo.name,tempString);
  580.                 
  581.                 for (j=0;j<16;j++)
  582.                     theFileInfo.finderInfo[j] = ((char *) &(myCPB.hFileInfo.ioFlFndrInfo))[j];
  583.                 
  584.                 for (j=0;j<16;j++)
  585.                     theFileInfo.finderInfo[j + 16] = ((char *) &(myCPB.hFileInfo.ioFlXFndrInfo))[j];
  586.                     
  587.                 byteCount = sizeof(FileInfo);
  588.                     
  589.                 if ((errCode = FSWrite(filesFRefNum,&byteCount,&theFileInfo))!=noErr)
  590.                 {
  591.                     sprintf(errorString,"ListDirectory:\rFSWrite(%s) error %d",MAPFILENAME,errCode);
  592.                     ErrorAlert(errorString);
  593.                     return(errCode);
  594.                 }
  595.             }
  596.         }
  597.         
  598.     } while (errCode==noErr);
  599.     
  600.     if (errCode == fnfErr)
  601.         errCode = noErr;
  602.     
  603.     
  604.     
  605.     if (errCode == noErr)
  606.     {
  607.         index = 1;
  608.             
  609.         do
  610.         {
  611.             tempString[0] = 0;
  612.             
  613.             myCPB.hFileInfo.ioCompletion = 0L;
  614.             myCPB.hFileInfo.ioNamePtr = (StringPtr) &tempString;
  615.             myCPB.hFileInfo.ioVRefNum = vRefNum;
  616.             myCPB.hFileInfo.ioFDirIndex = index++;
  617.             myCPB.hFileInfo.ioDirID = theIODirID;
  618.             
  619.             errCode = PBGetCatInfo(&myCPB,FALSE);
  620.             
  621.             if (errCode!=noErr && errCode!=fnfErr)
  622.             {
  623.                 sprintf(errorString,"ListDirectory:\rPBGetCatInfo error %d",errCode);
  624.                 ErrorAlert(errorString);
  625.                 return(errCode);
  626.             }
  627.             
  628.             else if (errCode == noErr && myCPB.hFileInfo.ioFlAttrib & 0x10 && myCPB.dirInfo.ioDrDirID != studentWorkDirID)
  629.             {
  630.                 PtoCstr(tempString);
  631.                 strcpy(errorString,currentDirName);
  632.                 strcat(currentDirName,":");
  633.                 strcat(currentDirName,tempString);
  634.                 strcpy(tempString,errorString);
  635.                 
  636.                 errCode = ListDirectory(dirsFRefNum,filesFRefNum,myCPB.hFileInfo.ioDirID);
  637.                 
  638.                 strcpy(currentDirName,tempString);
  639.             }
  640.             
  641.         } while (errCode==noErr);
  642.         
  643.         if (errCode == fnfErr)
  644.             errCode = noErr;
  645.     }    
  646.     
  647.     FlushVol("\p",vRefNum);
  648.     
  649.     return(errCode);
  650. }
  651.  
  652.  
  653.  
  654.  
  655. static void CenterWindow(WindowPtr wPtr)
  656. {
  657. int        screenWidth,screenHeight,windowWidth,windowHeight,left,top;
  658.  
  659.     if (wPtr == 0L)
  660.         return;
  661.     
  662.     screenWidth = screenBits.bounds.right - screenBits.bounds.left;
  663.     screenHeight = screenBits.bounds.bottom - screenBits.bounds.top - 20;
  664.     
  665.     windowWidth = wPtr->portRect.right - wPtr->portRect.left;
  666.     windowHeight = wPtr->portRect.bottom - wPtr->portRect.top;
  667.     
  668.     
  669.     left = screenBits.bounds.left + (screenWidth - windowWidth)/2;
  670.     
  671.     top = screenBits.bounds.top + 20 + (screenHeight - windowHeight)/2;
  672.     
  673.     if (left < 0)
  674.         left = 0;
  675.     
  676.     if (top < 20)
  677.         top = 20;
  678.     
  679.     MoveWindow(wPtr,left,top,FALSE);
  680. }
  681.  
  682.  
  683.  
  684. static pascal void HiliteDefaultButton(DialogPtr theDPtr,int whichItem)
  685. {
  686. int            type;
  687. Handle        theItem;
  688. Rect        theRect;
  689.  
  690.     GetDItem(theDPtr, ((DialogPeek) theDPtr)->aDefItem, &type, &theItem, &theRect);
  691.     PenNormal();
  692.     PenSize(3,3);
  693.     InsetRect(&theRect,-4,-4);
  694.     FrameRoundRect(&theRect,16,16);
  695.     PenSize(1,1);
  696. }
  697.  
  698.  
  699.  
  700. static void ErrorAlert(char *p0)
  701. {
  702. GrafPtr            oldPort;
  703. DialogPtr        theDPtr,tempDPtr;
  704. int                itemHit, type;
  705. Handle            theItem;
  706. Rect            theRect;
  707. EventRecord        theEvent;
  708.  
  709.     GetPort(&oldPort);
  710.     
  711.     InitCursor();
  712.     
  713.     if (!(theDPtr = GetNewDialog(ERRORDLOG, NULL,(WindowPtr) -1L)))
  714.     {
  715.         SysBeep(1);
  716.         ExitToShell();
  717.     }
  718.     
  719.     SetPort(theDPtr);
  720.     
  721.     CenterWindow(theDPtr);
  722.     ShowWindow(theDPtr);
  723.     
  724.     ((DialogPeek) theDPtr)->aDefItem = 1;
  725.     
  726.     GetDItem(theDPtr, 3, &type, &theItem, &theRect);
  727.     SetDItem(theDPtr, 3, type, HiliteDefaultButton, &theRect);
  728.     
  729.     GetDItem(theDPtr, 2, &type, &theItem, &theRect);
  730.     CtoPstr(p0);
  731.     SetIText(theItem, p0);
  732.     PtoCstr(p0);
  733.     
  734.     if (GetNextEvent(updateMask,&theEvent) && theEvent.message == (long) theDPtr)
  735.         DialogSelect(&theEvent,&tempDPtr,&itemHit);
  736.     
  737.     SysBeep(1);
  738.     
  739.     do 
  740.     {
  741.         itemHit = 0;
  742.         
  743.         while (!GetNextEvent(everyEvent,&theEvent));
  744.         
  745.         if (theEvent.what==keyDown || theEvent.what==autoKey)
  746.         {
  747.             if ((theEvent.message & charCodeMask)=='\r' || (theEvent.message & charCodeMask)==0x03)
  748.                 itemHit = ((DialogPeek) theDPtr)->aDefItem;
  749.             else
  750.                 SysBeep(1);
  751.         }
  752.         
  753.         else
  754.         {
  755.             tempDPtr = (DialogPtr) 0L;
  756.             
  757.             if (!IsDialogEvent(&theEvent) || !DialogSelect(&theEvent,&tempDPtr,&itemHit) || tempDPtr!=theDPtr)
  758.                 itemHit = 0;
  759.         }
  760.         
  761.     } while (itemHit!=1);
  762.     
  763.     DisposDialog(theDPtr);
  764.     SetPort(oldPort);
  765. }
  766.  
  767.  
  768.  
  769.  
  770. static int ContinueRenameDeleteQuit(char *thePrompt,int theDefault)
  771. {
  772. DialogPtr        theDPtr,tempDPtr;
  773. int                itemHit, type;
  774. Handle            theItem;
  775. Rect            tempRect;
  776. GrafPtr            oldPort;
  777. char            tempString[256];
  778. EventRecord        theEvent;
  779.  
  780.     GetPort(&oldPort);
  781.  
  782.     InitCursor();
  783.     
  784.     theDPtr = GetNewDialog(CRDQDLOG, 0L,(WindowPtr) -1L);
  785.     SetPort(theDPtr);
  786.     
  787.     CenterWindow(theDPtr);
  788.     ShowWindow(theDPtr);
  789.     
  790.     ((DialogPeek) theDPtr)->aDefItem = theDefault;
  791.     
  792.     GetDItem(theDPtr, 6, &type, &theItem, &tempRect);
  793.     SetDItem(theDPtr, 6, type, HiliteDefaultButton, &tempRect);
  794.     
  795.     strcpy(tempString,thePrompt);
  796.     CtoPstr(tempString);
  797.     GetDItem(theDPtr, 1, &type, &theItem, &tempRect);
  798.     SetIText(theItem, tempString);
  799.     
  800.     if (GetNextEvent(updateMask,&theEvent) && theEvent.message == (long) theDPtr)
  801.         DialogSelect(&theEvent,&tempDPtr,&itemHit);
  802.     
  803.     SysBeep(1);
  804.     
  805.     do 
  806.     {
  807.         ModalDialog(0L,&itemHit);
  808.         
  809.     } while (!(itemHit>=2 && itemHit<=5));
  810.     
  811.     DisposDialog(theDPtr);
  812.     SetPort(oldPort);
  813.     
  814.     return(itemHit);
  815. }
  816.  
  817.  
  818.  
  819. static int CreateRestoreQuit(char *thePrompt,int theDefault)
  820. {
  821. DialogPtr        theDPtr,tempDPtr;
  822. int                itemHit, type;
  823. Handle            theItem;
  824. Rect            tempRect;
  825. GrafPtr            oldPort;
  826. char            tempString[256];
  827. EventRecord        theEvent;
  828.  
  829.     GetPort(&oldPort);
  830.  
  831.     InitCursor();
  832.     
  833.     theDPtr = GetNewDialog(CRQDLOG, 0L,(WindowPtr) -1L);
  834.     SetPort(theDPtr);
  835.     
  836.     CenterWindow(theDPtr);
  837.     ShowWindow(theDPtr);
  838.     
  839.     ((DialogPeek) theDPtr)->aDefItem = theDefault;
  840.     
  841.     GetDItem(theDPtr, 5, &type, &theItem, &tempRect);
  842.     SetDItem(theDPtr, 5, type, HiliteDefaultButton, &tempRect);
  843.     
  844.     strcpy(tempString,thePrompt);
  845.     CtoPstr(tempString);
  846.     GetDItem(theDPtr, 4, &type, &theItem, &tempRect);
  847.     SetIText(theItem, tempString);
  848.     
  849.     if (GetNextEvent(updateMask,&theEvent) && theEvent.message == (long) theDPtr)
  850.         DialogSelect(&theEvent,&tempDPtr,&itemHit);
  851.     
  852.     SysBeep(1);
  853.     
  854.     do 
  855.     {
  856.         ModalDialog(0L,&itemHit);
  857.         
  858.     } while (!(itemHit>=1 && itemHit<=3));
  859.     
  860.     DisposDialog(theDPtr);
  861.     SetPort(oldPort);
  862.     
  863.     return(itemHit);
  864. }
  865.  
  866.  
  867.  
  868.  
  869.  
  870. static int LoadAndParseFiles(void)
  871. {
  872. char        filesFName[256];
  873. int            errCode;
  874. int            filesFRefNum;
  875. long        byteCount,theSize;
  876.  
  877.  
  878.     DisposeFileList();
  879.     
  880.     errCode = SetupVolRefNum();
  881.     
  882.     if (errCode != noErr)
  883.         return(errCode);
  884.     
  885.     strcpy(filesFName,FILELISTNAME);
  886.     CtoPstr(filesFName);
  887.     
  888.     errCode=FSOpen(filesFName,sysFolderVRefNum,&filesFRefNum);
  889.         
  890.     if (errCode!=noErr)
  891.     {
  892.         sprintf(errorString,"LoadAndParseFiles:\rFSOpen('%s') error %d",FILELISTNAME,errCode);
  893.         ErrorAlert(errorString);
  894.         return(errCode);
  895.     }
  896.     
  897.     if ((errCode = SetFPos(filesFRefNum,fsFromStart,0L))!=noErr)
  898.     {
  899.         FSClose(filesFRefNum);
  900.         sprintf(errorString,"LoadAndParseFiles:\rSetFPos('%s',fsFromStart) error %d",FILELISTNAME,errCode);
  901.         ErrorAlert(errorString);
  902.         return(errCode);
  903.     }
  904.     
  905.     if ((errCode = GetEOF(filesFRefNum,&theSize))!=noErr)
  906.     {
  907.         FSClose(filesFRefNum);
  908.         sprintf(errorString,"LoadAndParseFiles:\rGetEOF('%s') error %d",FILELISTNAME,errCode);
  909.         ErrorAlert(errorString);
  910.         return(errCode);
  911.     }
  912.     
  913.     numFiles = theSize / sizeof(FileInfo);
  914.     
  915.     if (theSize % sizeof(FileInfo))
  916.     {
  917.         DisposeFileList();
  918.         FSClose(filesFRefNum);
  919.         sprintf(errorString,"LoadAndParseFiles:\rbad file size-- %ld extra bytes ",theSize - (numFiles * sizeof(FileInfo)));
  920.         ErrorAlert(errorString);
  921.         return(errCode);
  922.     }
  923.     
  924.     
  925.     listOfFiles = (FileInfo *) NewPtr(numFiles * sizeof(FileInfo));
  926.     
  927.     byteCount = numFiles * sizeof(FileInfo);
  928.     
  929.     if ((errCode = FSRead(filesFRefNum,&byteCount,(Ptr) listOfFiles))!=noErr)
  930.     {
  931.         DisposeFileList();
  932.         FSClose(filesFRefNum);
  933.         sprintf(errorString,"LoadAndParseFiles:\rFSRead('%s') error %d",FILELISTNAME,errCode);
  934.         ErrorAlert(errorString);
  935.         return(errCode);
  936.     }
  937.     
  938.     if ((errCode = FSClose(filesFRefNum))!=noErr)
  939.     {
  940.         DisposeFileList();
  941.         sprintf(errorString,"LoadAndParseFiles:\rFSClose('%s') error %d",FILELISTNAME,errCode);
  942.         ErrorAlert(errorString);
  943.         return(errCode);
  944.     }
  945.     
  946.     
  947.     return(noErr);
  948. }
  949.  
  950.  
  951.  
  952.  
  953. static void DisposeFileList(void)
  954. {
  955.     if (listOfFiles)
  956.         DisposPtr(listOfFiles);
  957.     
  958.     listOfFiles = 0L;
  959.     numFiles = 0L;
  960. }
  961.  
  962.  
  963. static int LoadAndParseDirs(void)
  964. {
  965. char        dirsFName[256];
  966. int            errCode;
  967. int            dirsFRefNum;
  968. long        byteCount,theSize;
  969.  
  970.  
  971.     DisposeDirList();
  972.     
  973.     errCode = SetupVolRefNum();
  974.     
  975.     if (errCode != noErr)
  976.         return(errCode);
  977.     
  978.     strcpy(dirsFName,MAPFILENAME);
  979.     CtoPstr(dirsFName);
  980.     
  981.     errCode=FSOpen(dirsFName,sysFolderVRefNum,&dirsFRefNum);
  982.         
  983.     if (errCode!=noErr)
  984.     {
  985.         sprintf(errorString,"LoadAndParseDirs:\rFSOpen('%s') error %d",MAPFILENAME,errCode);
  986.         ErrorAlert(errorString);
  987.         return(errCode);
  988.     }
  989.     
  990.     if ((errCode = SetFPos(dirsFRefNum,fsFromStart,0L))!=noErr)
  991.     {
  992.         FSClose(dirsFRefNum);
  993.         sprintf(errorString,"LoadAndParseDirs:\rSetFPos('%s',fsFromStart) error %d",MAPFILENAME,errCode);
  994.         ErrorAlert(errorString);
  995.         return(errCode);
  996.     }
  997.     
  998.     if ((errCode = GetEOF(dirsFRefNum,&theSize))!=noErr)
  999.     {
  1000.         FSClose(dirsFRefNum);
  1001.         sprintf(errorString,"LoadAndParseDirs:\rGetEOF('%s') error %d",MAPFILENAME,errCode);
  1002.         ErrorAlert(errorString);
  1003.         return(errCode);
  1004.     }
  1005.     
  1006.     
  1007.     byteCount = sizeof(VolumeInfo);
  1008.     
  1009.     if ((errCode = FSRead(dirsFRefNum,&byteCount,&theVolInfo))!=noErr)
  1010.     {
  1011.         FSClose(dirsFRefNum);
  1012.         sprintf(errorString,"LoadAndParseDirs:\rFSRead('%s') error %d",MAPFILENAME,errCode);
  1013.         ErrorAlert(errorString);
  1014.         return(errCode);
  1015.     }
  1016.     
  1017.     theSize -= byteCount;
  1018.     numDirs = theSize / sizeof(DirInfo);
  1019.     
  1020.     if (theSize % sizeof(DirInfo))
  1021.     {
  1022.         DisposeDirList();
  1023.         FSClose(dirsFRefNum);
  1024.         sprintf(errorString,"LoadAndParseDirs:\rbad file size-- %ld extra bytes ",theSize - (numDirs * sizeof(DirInfo)));
  1025.         ErrorAlert(errorString);
  1026.         return(errCode);
  1027.     }
  1028.     
  1029.     
  1030.     listOfDirs = (DirInfo *) NewPtr(numDirs * sizeof(DirInfo));
  1031.     
  1032.     byteCount = numDirs * sizeof(DirInfo);
  1033.     
  1034.     if ((errCode = FSRead(dirsFRefNum,&byteCount,(Ptr) listOfDirs))!=noErr)
  1035.     {
  1036.         DisposeDirList();
  1037.         FSClose(dirsFRefNum);
  1038.         sprintf(errorString,"LoadAndParseDirs:\rFSRead('%s') error %d",MAPFILENAME,errCode);
  1039.         ErrorAlert(errorString);
  1040.         return(errCode);
  1041.     }
  1042.     
  1043.     if ((errCode = FSClose(dirsFRefNum))!=noErr)
  1044.     {
  1045.         DisposeDirList();
  1046.         sprintf(errorString,"LoadAndParseDirs:\rFSClose('%s') error %d",MAPFILENAME,errCode);
  1047.         ErrorAlert(errorString);
  1048.         return(errCode);
  1049.     }
  1050.     
  1051.     
  1052.     return(noErr);
  1053. }
  1054.  
  1055.  
  1056.  
  1057.  
  1058. static void DisposeDirList(void)
  1059. {
  1060.     if (listOfDirs)
  1061.         DisposePtr(listOfDirs);
  1062.     
  1063.     listOfDirs = 0L;
  1064.     numDirs = 0L;
  1065. }
  1066.  
  1067.  
  1068.  
  1069.  
  1070.  
  1071. static int OptionKey(void)
  1072. {
  1073. char    theKeyMap[16];
  1074.  
  1075.     GetKeys(theKeyMap);
  1076.     
  1077.     if (theKeyMap[7] & 0x04)
  1078.         return(TRUE);
  1079.     else
  1080.         return(FALSE);
  1081. }
  1082.  
  1083.  
  1084.  
  1085.  
  1086.  
  1087.  
  1088.  
  1089. static int CompareFiles(FileInfo *first,FileInfo *second)
  1090. {
  1091. int        errCode;
  1092.  
  1093.     if (first && second)
  1094.     {
  1095.         errCode = strcmp(first->name,second->name);
  1096.         
  1097.         if (errCode > 0)
  1098.             return(1);
  1099.         
  1100.         else if (errCode < 0)
  1101.             return(-1);
  1102.         
  1103.         
  1104.         if (first->creator > second->creator)
  1105.             return(1);
  1106.         
  1107.         else if (first->creator < second->creator)
  1108.             return(-1);
  1109.         
  1110.         
  1111.         
  1112.         if (first->type > second->type)
  1113.             return(1);
  1114.         
  1115.         else if (first->type < second->type)
  1116.             return(-1);
  1117.         
  1118.         
  1119.         
  1120.         if (first->creationDate > second->creationDate)
  1121.             return(1);
  1122.         
  1123.         else if (first->creationDate < second->creationDate)
  1124.             return(-1);
  1125.         
  1126.         
  1127.         
  1128.         if (first->parentDirID > second->parentDirID)
  1129.             return(1);
  1130.         
  1131.         else if (first->parentDirID < second->parentDirID)
  1132.             return(-1);
  1133.         
  1134.         
  1135.         
  1136.         return(0);
  1137.     }
  1138.     
  1139.     return(0);
  1140. }
  1141.  
  1142.  
  1143.  
  1144. static int    SortFileList(void)
  1145. {
  1146. register long    i,j,least;
  1147. int                errCode;
  1148. int                filesFRefNum;
  1149. long            byteCount;
  1150. char            filesFName[256];
  1151. FileInfo        swap;
  1152.  
  1153.     errCode = LoadAndParseFiles();
  1154.     
  1155.     if (errCode != noErr)
  1156.         return(errCode);
  1157.     
  1158.     SetInfoMessage("Now sorting files list....");
  1159.     
  1160.     for (i = 0;i < numFiles;i++)
  1161.     {
  1162.         if (InfoBreak())
  1163.         {
  1164.             DisposeFileList();
  1165.             return(-1);
  1166.         }
  1167.         
  1168.         least = i;
  1169.         
  1170.         for (j = i+1L;j < numFiles;j++)
  1171.         {
  1172.             if (CompareFiles(&(listOfFiles[j]),&(listOfFiles[least])) < 0)
  1173.                 least = j;
  1174.         }
  1175.         
  1176.         if (least != i)
  1177.         {
  1178.             swap = listOfFiles[i];
  1179.             listOfFiles[i] = listOfFiles[least];
  1180.             listOfFiles[least] = swap;
  1181.         }
  1182.         
  1183.         sprintf(errorString,"Sorting %ld/%ld = %ld%%  (%s)",i+1,numFiles,(long) ((100L * (i + 1L))/numFiles),listOfFiles[i].name);
  1184.         SetInfoMessage(errorString);
  1185.     }
  1186.     
  1187.     
  1188.     SetInfoMessage("Writing sorted file list....");
  1189.     
  1190.     strcpy(filesFName,FILELISTNAME);
  1191.     CtoPstr(filesFName);
  1192.     
  1193.     errCode = FSOpen(filesFName,sysFolderVRefNum,&filesFRefNum);
  1194.         
  1195.     if (errCode!=noErr)
  1196.     {
  1197.         DisposeFileList();
  1198.         sprintf(errorString,"SortFileList:\rFSOpen('%s') error %d",FILELISTNAME,errCode);
  1199.         ErrorAlert(errorString);
  1200.         return(errCode);
  1201.     }
  1202.     
  1203.     if ((errCode = SetFPos(filesFRefNum,fsFromStart,0L))!=noErr)
  1204.     {
  1205.         DisposeFileList();
  1206.         FSClose(filesFRefNum);
  1207.         sprintf(errorString,"SortFileList:\rSetFPos('%s',fsFromStart) error %d",FILELISTNAME,errCode);
  1208.         ErrorAlert(errorString);
  1209.         return(errCode);
  1210.     }
  1211.     
  1212.     if ((errCode = SetEOF(filesFRefNum,0L))!=noErr)
  1213.     {
  1214.         DisposeFileList();
  1215.         FSClose(filesFRefNum);
  1216.         sprintf(errorString,"SortFileList:\rSetEOF('%s') error %d",FILELISTNAME,errCode);
  1217.         ErrorAlert(errorString);
  1218.         return(errCode);
  1219.     }
  1220.     
  1221.     byteCount = numFiles * sizeof(FileInfo);
  1222.         
  1223.     if ((errCode = FSWrite(filesFRefNum,&byteCount,listOfFiles))!=noErr)
  1224.     {
  1225.         DisposeFileList();
  1226.         sprintf(errorString,"SortFileList:\rFSWrite(%s) error %d",FILELISTNAME,errCode);
  1227.         ErrorAlert(errorString);
  1228.         FSClose(filesFRefNum);
  1229.         return(errCode);
  1230.     }
  1231.             
  1232.     if ((errCode = FSClose(filesFRefNum))!=noErr)
  1233.     {
  1234.         DisposeFileList();
  1235.         sprintf(errorString,"SortFileList:\rFSClose(%s) error %d",FILELISTNAME,errCode);
  1236.         ErrorAlert(errorString);
  1237.         return(errCode);
  1238.     }
  1239.             
  1240.     DisposeFileList();
  1241.     
  1242.     
  1243.     return(noErr);
  1244. }
  1245.  
  1246.  
  1247.  
  1248.  
  1249. static long FindFile(FileInfo *theFileInfo)
  1250. {
  1251. register long    i,delta,found,matchWeight,tempWeight;
  1252.  
  1253.     i = 0;
  1254.     
  1255.     if (numFiles & 1L)
  1256.         delta = (numFiles / 2L) + 1L;
  1257.     else
  1258.         delta = (numFiles / 2L);
  1259.     
  1260.     found = -1L;
  1261.     
  1262.     while (delta >= 1L && found < 0L)
  1263.     {
  1264.         tempWeight = CompareFiles(&(listOfFiles[i]),theFileInfo);
  1265.         
  1266.         if (tempWeight == 0L)
  1267.             return(i);
  1268.         
  1269.         else if (tempWeight < 0L)
  1270.             i += delta;
  1271.         
  1272.         else
  1273.             i -= delta;
  1274.         
  1275.         
  1276.         if (delta == 1L)
  1277.             delta = 0L;
  1278.         
  1279.         else if (delta & 1L)
  1280.             delta = (delta >> 1L) + 1L;
  1281.         else
  1282.             delta = (delta >> 1L);
  1283.     }
  1284.     
  1285.     found = -1L;
  1286.     matchWeight = 0;
  1287.     
  1288.     for (i = 0;i < numFiles;i++)
  1289.     {
  1290.         tempWeight = 0;
  1291.         
  1292.         if (strcmp(theFileInfo->name,listOfFiles[i].name) == EQSTR)
  1293.             tempWeight++;
  1294.         
  1295.         if (theFileInfo->creator == listOfFiles[i].creator)
  1296.             tempWeight++;
  1297.         
  1298.         if (theFileInfo->type == listOfFiles[i].type)
  1299.             tempWeight++;
  1300.         
  1301.         if (theFileInfo->creationDate == listOfFiles[i].creationDate)
  1302.             tempWeight++;
  1303.         
  1304.         if (theFileInfo->parentDirID == listOfFiles[i].parentDirID)
  1305.             tempWeight++;
  1306.         
  1307.         if (theFileInfo->attrib == listOfFiles[i].attrib)
  1308.             tempWeight++;
  1309.         
  1310.         if (strcmp(theFileInfo->finderInfo,listOfFiles[i].finderInfo) == EQSTR)
  1311.             tempWeight++;
  1312.         
  1313.         
  1314.         
  1315.         if (tempWeight > matchWeight)
  1316.         {
  1317.             matchWeight = tempWeight;
  1318.             found = i;
  1319.         }
  1320.     }
  1321.     
  1322.     
  1323.     if (found >= 0L && (theFileInfo->creator != listOfFiles[found].creator || 
  1324.         theFileInfo->type != listOfFiles[found].type || 
  1325.         theFileInfo->creationDate != listOfFiles[found].creationDate))
  1326.             found = -1L;
  1327.     
  1328.     return(found);
  1329. }
  1330.  
  1331.  
  1332.  
  1333.  
  1334.  
  1335. static int CompareDirs(DirInfo *first,DirInfo *second)
  1336. {
  1337. int        errCode;
  1338.  
  1339.     if (first && second)
  1340.     {
  1341.         errCode = strcmp(first->name,second->name);
  1342.         
  1343.         if (errCode > 0)
  1344.             return(1);
  1345.         
  1346.         else if (errCode < 0)
  1347.             return(-1);
  1348.         
  1349.         
  1350.         if (first->dirID > second->dirID)
  1351.             return(1);
  1352.         
  1353.         else if (first->dirID < second->dirID)
  1354.             return(-1);
  1355.         
  1356.         
  1357.         
  1358.         if (first->parentDirID > second->parentDirID)
  1359.             return(1);
  1360.         
  1361.         else if (first->parentDirID < second->parentDirID)
  1362.             return(-1);
  1363.         
  1364.         
  1365.         if (first->attrib > second->attrib)
  1366.             return(1);
  1367.         
  1368.         else if (first->attrib < second->attrib)
  1369.             return(-1);
  1370.         
  1371.         
  1372.         
  1373.         errCode = strcmp(first->finderInfo,second->finderInfo);
  1374.         
  1375.         if (errCode > 0)
  1376.             return(1);
  1377.         
  1378.         else if (errCode < 0)
  1379.             return(-1);
  1380.         
  1381.         return(0);
  1382.     }
  1383.     
  1384.     return(0);
  1385. }
  1386.  
  1387.  
  1388.  
  1389. static int    SortDirList(void)
  1390. {
  1391. register long    i,j,least;
  1392. int                errCode;
  1393. int                dirsFRefNum;
  1394. long            byteCount;
  1395. char            dirsFName[256];
  1396. DirInfo            swap;
  1397.  
  1398.     errCode = LoadAndParseDirs();
  1399.     
  1400.     if (errCode != noErr)
  1401.         return(errCode);
  1402.     
  1403.     SetInfoMessage("Beginning sort of directories....");
  1404.     
  1405.     for (i = 0;i < numDirs;i++)
  1406.     {
  1407.         if (InfoBreak())
  1408.         {
  1409.             DisposeDirList();
  1410.             return(-1);
  1411.         }
  1412.         
  1413.         least = i;
  1414.         
  1415.         for (j = i+1L;j < numDirs;j++)
  1416.         {
  1417.             if (CompareDirs(&(listOfDirs[j]),&(listOfDirs[least])) < 0)
  1418.                 least = j;
  1419.         }
  1420.         
  1421.         if (least != i)
  1422.         {
  1423.             swap = listOfDirs[i];
  1424.             listOfDirs[i] = listOfDirs[least];
  1425.             listOfDirs[least] = swap;
  1426.         }
  1427.         
  1428.         sprintf(errorString,"Sorting %ld/%ld = %ld%%  (%s)",i+1,numDirs,(long) ((100L * (i + 1L))/numDirs),listOfDirs[i].name);
  1429.         SetInfoMessage(errorString);
  1430.     }
  1431.     
  1432.     
  1433.     SetInfoMessage("Writing sorted directory list....");
  1434.     
  1435.     strcpy(dirsFName,MAPFILENAME);
  1436.     CtoPstr(dirsFName);
  1437.     
  1438.     errCode = FSOpen(dirsFName,sysFolderVRefNum,&dirsFRefNum);
  1439.         
  1440.     if (errCode!=noErr)
  1441.     {
  1442.         DisposeDirList();
  1443.         sprintf(errorString,"SortDirList:\rFSOpen('%s') error %d",MAPFILENAME,errCode);
  1444.         ErrorAlert(errorString);
  1445.         return(errCode);
  1446.     }
  1447.     
  1448.     if ((errCode = SetFPos(dirsFRefNum,fsFromStart,0L))!=noErr)
  1449.     {
  1450.         DisposeDirList();
  1451.         FSClose(dirsFRefNum);
  1452.         sprintf(errorString,"SortDirList:\rSetFPos('%s',fsFromStart) error %d",MAPFILENAME,errCode);
  1453.         ErrorAlert(errorString);
  1454.         return(errCode);
  1455.     }
  1456.     
  1457.     if ((errCode = SetEOF(dirsFRefNum,0L))!=noErr)
  1458.     {
  1459.         DisposeDirList();
  1460.         FSClose(dirsFRefNum);
  1461.         sprintf(errorString,"SortDirList:\rSetEOF('%s') error %d",MAPFILENAME,errCode);
  1462.         ErrorAlert(errorString);
  1463.         return(errCode);
  1464.     }
  1465.     
  1466.     byteCount = sizeof(VolumeInfo);
  1467.     
  1468.     if ((errCode = FSWrite(dirsFRefNum,&byteCount,&theVolInfo))!=noErr)
  1469.     {
  1470.         DisposeDirList();
  1471.         sprintf(errorString,"SortDirList:\rFSWrite(%s) error %d",MAPFILENAME,errCode);
  1472.         ErrorAlert(errorString);
  1473.         FSClose(dirsFRefNum);
  1474.         return(errCode);
  1475.     }
  1476.     
  1477.     byteCount = numDirs * sizeof(DirInfo);
  1478.         
  1479.     if ((errCode = FSWrite(dirsFRefNum,&byteCount,listOfDirs))!=noErr)
  1480.     {
  1481.         DisposeDirList();
  1482.         sprintf(errorString,"SortDirList:\rFSWrite(%s) error %d",MAPFILENAME,errCode);
  1483.         ErrorAlert(errorString);
  1484.         FSClose(dirsFRefNum);
  1485.         return(errCode);
  1486.     }
  1487.             
  1488.     if ((errCode = FSClose(dirsFRefNum))!=noErr)
  1489.     {
  1490.         DisposeDirList();
  1491.         sprintf(errorString,"SortDirList:\rFSClose(%s) error %d",MAPFILENAME,errCode);
  1492.         ErrorAlert(errorString);
  1493.         FSClose(dirsFRefNum);
  1494.         return(errCode);
  1495.     }
  1496.             
  1497.     DisposeDirList();
  1498.     
  1499.     
  1500.     return(noErr);
  1501. }
  1502.  
  1503.  
  1504.  
  1505.  
  1506.  
  1507. static long FindDir(DirInfo *theDirInfo)
  1508. {
  1509. register long    i,delta,result;
  1510.  
  1511.     i = 0;
  1512.     
  1513.     
  1514.     if (numDirs & 1L)
  1515.         delta = (numDirs / 2L) + 1L;
  1516.     else
  1517.         delta = (numDirs / 2L);
  1518.     
  1519.     
  1520.     while (delta >= 1L)
  1521.     {
  1522.         result = CompareDirs(&(listOfDirs[i]),theDirInfo);
  1523.         
  1524.         if (result == 0L)
  1525.             return(i);
  1526.         
  1527.         else if (result < 0L)
  1528.             i += delta;
  1529.         
  1530.         else
  1531.             i -= delta;
  1532.         
  1533.         
  1534.         if (delta == 1L)
  1535.             delta = 0L;
  1536.         
  1537.         else if (delta & 1L)
  1538.             delta = (delta >> 1L) + 1L;
  1539.         else
  1540.             delta = (delta >> 1L);
  1541.     }
  1542.     
  1543.     
  1544.     for (i = 0;i < numDirs;i++)
  1545.     {
  1546.         if (theDirInfo->dirID == listOfDirs[i].dirID)
  1547.             return(i);
  1548.     }
  1549.     
  1550.     return(-1L);
  1551. }
  1552.  
  1553.  
  1554.  
  1555.  
  1556.  
  1557.  
  1558.  
  1559.  
  1560.  
  1561. static int ResetVolumeAndDirs(void)
  1562. {
  1563. int                errCode;
  1564. HParamBlockRec    myHPB;
  1565. CMovePBRec        myCMovePB;
  1566. WDPBRec            myWDPB;
  1567. int                j,i;
  1568. char            tempString[256];
  1569. long            theParentDirID;
  1570.  
  1571.     errCode = SetupVolRefNum();
  1572.     
  1573.     if (errCode != noErr)
  1574.         return(errCode);
  1575.     
  1576.     tempString[0] = 0;
  1577.     
  1578.     myHPB.volumeParam.ioCompletion = 0L;
  1579.     myHPB.volumeParam.ioNamePtr = (StringPtr) &tempString;
  1580.     myHPB.volumeParam.ioVRefNum = vRefNum;
  1581.     myHPB.volumeParam.ioVolIndex = 0;
  1582.     
  1583.     errCode = PBHGetVInfo(&myHPB,FALSE);
  1584.     
  1585.     if (errCode != noErr)
  1586.     {
  1587.         sprintf(errorString,"ResetVolumeAndDirs:\rPBHGetVInfo() error %d",errCode);
  1588.         ErrorAlert(errorString);
  1589.         return(errCode);
  1590.     }
  1591.     
  1592.     SetInfoMessage("Loading previously saved volume/directory information");
  1593.     
  1594.     errCode = LoadAndParseDirs();
  1595.     
  1596.     if (errCode != noErr)
  1597.         return(errCode);
  1598.     
  1599.     PtoCstr(tempString);
  1600.     errCode = strcmp(tempString,theVolInfo.name);
  1601.     CtoPstr(tempString);
  1602.     
  1603.     if (errCode != EQSTR)
  1604.     {
  1605.         PtoCstr(tempString);
  1606.         sprintf(errorString,"Renaming volume from '%s' to '%s'",tempString,theVolInfo.name);
  1607.         CtoPstr(tempString);
  1608.         SetInfoMessage(errorString);
  1609.         
  1610.         strcpy(errorString,theVolInfo.name);
  1611.         CtoPstr(errorString);
  1612.         
  1613.         myHPB.volumeParam.ioCompletion = 0L;
  1614.         myHPB.volumeParam.ioNamePtr = 0L;
  1615.         myHPB.volumeParam.ioVRefNum = vRefNum;
  1616.         myHPB.ioParam.ioMisc = (Ptr) &errorString;
  1617.         myHPB.fileParam.ioDirID = 0;
  1618.         
  1619.         errCode = PBHRename(&myHPB,FALSE);
  1620.         
  1621.         if (errCode != noErr)
  1622.         {
  1623.             PtoCstr(tempString);
  1624.             sprintf(errorString,"ResetVolumeAndDirs:\rPBHRename('%s' -> '%s') error %d",tempString,theVolInfo.name,errCode);
  1625.             CtoPstr(tempString);
  1626.             ErrorAlert(errorString);
  1627.         }
  1628.         
  1629.         else
  1630.         {
  1631.             strcpy(tempString,theVolInfo.name);
  1632.             CtoPstr(tempString);
  1633.         }
  1634.     }
  1635.     
  1636.     
  1637.     myHPB.volumeParam.ioCompletion = 0L;
  1638.     myHPB.volumeParam.ioNamePtr = (StringPtr) &tempString;
  1639.     myHPB.volumeParam.ioVAtrb = theVolInfo.attrib;
  1640.     
  1641.     for (j=0;j<32;j++)
  1642.         ((unsigned char *) &(myHPB.volumeParam.ioVFndrInfo))[j] = theVolInfo.finderInfo[j];
  1643.     
  1644.     SetInfoMessage("Resetting volume info");
  1645.     
  1646.     errCode = PBSetVInfo(&myHPB,FALSE);
  1647.     
  1648.     if (errCode != noErr)
  1649.     {
  1650.         sprintf(errorString,"ResetVolumeAndDirs:\rPBSetVInfo() error %d",errCode);
  1651.         ErrorAlert(errorString);
  1652.         return(errCode);
  1653.     }
  1654.     
  1655.     SetInfoMessage("Beginning reset of directory information");
  1656.     
  1657.     for (i=0;i<numDirs;i++)
  1658.     {
  1659.         if (InfoBreak())
  1660.         {
  1661.             DisposeDirList();
  1662.             return(-1);
  1663.         }
  1664.         
  1665.         tempString[0] = 0;
  1666.         
  1667.         myCPB.dirInfo.ioCompletion = 0L;
  1668.         myCPB.dirInfo.ioNamePtr = (StringPtr) &tempString;
  1669.         myCPB.dirInfo.ioVRefNum = vRefNum;
  1670.         myCPB.dirInfo.ioFDirIndex = -1;
  1671.         myCPB.dirInfo.ioDrDirID = listOfDirs[i].dirID;
  1672.         
  1673.         errCode = PBGetCatInfo(&myCPB,FALSE);
  1674.         
  1675.         if (errCode == fnfErr)
  1676.         {
  1677.             sprintf(errorString,"ResetVolumeAndDirs:\rPBGetCatInfo('%s') error %d \r\rDirectory has probably been deleted...",listOfDirs[i].name,errCode);
  1678.             ErrorAlert(errorString);
  1679.         }
  1680.         
  1681.         else if (errCode != noErr)
  1682.         {
  1683.             sprintf(errorString,"ResetVolumeAndDirs:\rPBGetCatInfo('%s') error %d",listOfDirs[i].name,errCode);
  1684.             ErrorAlert(errorString);
  1685.         }
  1686.         
  1687.         else
  1688.         {
  1689.             theParentDirID = myCPB.dirInfo.ioDrParID;
  1690.             
  1691.             PtoCstr(tempString);
  1692.             errCode = strcmp(tempString,listOfDirs[i].name);
  1693.             CtoPstr(tempString);
  1694.             
  1695.             if (errCode != EQSTR)
  1696.             {
  1697.                 myWDPB.ioCompletion = 0L;
  1698.                 myWDPB.ioNamePtr = 0L;
  1699.                 myWDPB.ioVRefNum = vRefNum;
  1700.                 myWDPB.ioWDProcID = CREATOR;
  1701.                 myWDPB.ioWDDirID = myCPB.dirInfo.ioDrParID;
  1702.                 
  1703.                 errCode = PBOpenWD(&myWDPB,FALSE);
  1704.                 
  1705.                 if (errCode != noErr)
  1706.                 {
  1707.                     sprintf(errorString,"ResetVolumeAndDirs:\rPBOpenWD() error %d",errCode);
  1708.                     ErrorAlert(errorString);
  1709.                 }
  1710.                 
  1711.                 else
  1712.                 {
  1713.                     PtoCstr(tempString);
  1714.                     sprintf(errorString,"Renaming directory from '%s' to '%s'",tempString,listOfDirs[i].name);
  1715.                     CtoPstr(tempString);
  1716.                     SetInfoMessage(errorString);
  1717.                     
  1718.                     strcpy(errorString,listOfDirs[i].name);
  1719.                     CtoPstr(errorString);
  1720.                     
  1721.                     myHPB.fileParam.ioCompletion = 0L;
  1722.                     myHPB.fileParam.ioNamePtr = (StringPtr) tempString;
  1723.                     myHPB.fileParam.ioVRefNum = myWDPB.ioVRefNum;
  1724.                     myHPB.ioParam.ioMisc = (Ptr) &errorString;
  1725.                     myHPB.fileParam.ioDirID = 0L;
  1726.                     
  1727.                     errCode = PBHRename(&myHPB,FALSE);
  1728.                     
  1729.                     if (errCode != noErr)
  1730.                     {
  1731.                         PtoCstr(tempString);
  1732.                         sprintf(errorString,"ResetVolumeAndDirs:\rPBHRename('%s' -> '%s') error %d",tempString,listOfDirs[i].name,errCode);
  1733.                         CtoPstr(tempString);
  1734.                         ErrorAlert(errorString);
  1735.                     }
  1736.                     
  1737.                     else
  1738.                     {
  1739.                         strcpy(tempString,listOfDirs[i].name);
  1740.                         CtoPstr(tempString);
  1741.                     }
  1742.                     
  1743.                     errCode = PBCloseWD(&myWDPB,FALSE);
  1744.                 }
  1745.             }
  1746.             
  1747.             myCPB.dirInfo.ioCompletion = 0L;
  1748.             myCPB.dirInfo.ioNamePtr = 0L;
  1749.             myCPB.dirInfo.ioVRefNum = vRefNum;
  1750.             myCPB.dirInfo.ioFlAttrib = listOfDirs[i].attrib;
  1751.             myCPB.dirInfo.ioDrDirID = listOfDirs[i].dirID;
  1752.             
  1753.             for (j=0;j<16;j++)
  1754.                 ((char *) &(myCPB.dirInfo.ioDrUsrWds))[j] = listOfDirs[i].finderInfo[j];
  1755.             
  1756.             for (j=0;j<16;j++)
  1757.                 ((char *) &(myCPB.dirInfo.ioDrFndrInfo))[j] = listOfDirs[i].finderInfo[j + 16];
  1758.             
  1759.             errCode = PBSetCatInfo(&myCPB,FALSE);
  1760.             
  1761.             if (errCode != noErr)
  1762.             {
  1763.                 PtoCstr(tempString);
  1764.                 sprintf(errorString,"ResetVolumeAndDirs:\rPBSetCatInfo(%s) error %d",tempString,errCode);
  1765.                 CtoPstr(tempString);
  1766.                 ErrorAlert(errorString);
  1767.             }
  1768.             
  1769.             if (theParentDirID != listOfDirs[i].parentDirID)
  1770.             {
  1771.                 PtoCstr(tempString);
  1772.                 sprintf(errorString,"Moving '%s'",tempString);
  1773.                 CtoPstr(tempString);
  1774.                 SetInfoMessage(errorString);
  1775.                 
  1776.                 myCMovePB.ioCompletion = 0L;
  1777.                 myCMovePB.ioNamePtr = 0L;
  1778.                 myCMovePB.ioVRefNum = vRefNum;
  1779.                 myCMovePB.ioNewName = 0L;
  1780.                 myCMovePB.ioNewDirID = listOfDirs[i].parentDirID;
  1781.                 myCMovePB.ioDirID = listOfDirs[i].dirID;
  1782.                 
  1783.                 errCode = PBCatMove(&myCMovePB,FALSE);
  1784.                 
  1785.                 if (errCode != noErr)
  1786.                 {
  1787.                     PtoCstr(tempString);
  1788.                     sprintf(errorString,"ResetVolumeAndDirs:\rPBCatMove(%s) error %d",tempString,errCode);
  1789.                     CtoPstr(tempString);
  1790.                     ErrorAlert(errorString);
  1791.                 }
  1792.             }
  1793.         }
  1794.     }
  1795.     
  1796.     DisposeDirList();
  1797. }
  1798.  
  1799.  
  1800.  
  1801.  
  1802. static int ResetFilesAndCollectGarbage(void)
  1803. {
  1804. int        errCode;
  1805. char    tempString[256];
  1806.  
  1807.  
  1808.     errCode = SetupVolRefNum();
  1809.     
  1810.     if (errCode != noErr)
  1811.         return(errCode);
  1812.     
  1813.     errCode = LoadAndParseDirs();
  1814.     
  1815.     if (errCode != noErr)
  1816.         return(errCode);
  1817.     
  1818.     errCode = LoadAndParseFiles();
  1819.     
  1820.     if (errCode != noErr)
  1821.         return(errCode);
  1822.     
  1823.     strcpy(currentDirName,theVolInfo.name);
  1824.     
  1825.     ProcessDirectory(0L);
  1826.     
  1827.     FlushVol("\p",vRefNum);
  1828.     
  1829. }
  1830.  
  1831.  
  1832.  
  1833.  
  1834. static int  ProcessDirectory(long theIODirID)
  1835. {
  1836. int                index,errCode,j;
  1837. char            tempString[256];
  1838. long            match;
  1839. CMovePBRec        myCMovePB;
  1840. WDPBRec            myWDPB;
  1841. HParamBlockRec    myHPB;
  1842.  
  1843.  
  1844.     if (InfoBreak())
  1845.         return(-1);
  1846.     
  1847.     if (currentDirName[0])
  1848.     {
  1849.         sprintf(errorString,"Checking %s",currentDirName);
  1850.         SetInfoMessage(errorString);
  1851.     }
  1852.     
  1853.     index = 1;
  1854.         
  1855.     do
  1856.     {
  1857.         tempString[0] = 0;
  1858.         
  1859.         myCPB.hFileInfo.ioCompletion = 0L;
  1860.         myCPB.hFileInfo.ioNamePtr = (StringPtr) &tempString;
  1861.         myCPB.hFileInfo.ioVRefNum = vRefNum;
  1862.         myCPB.hFileInfo.ioFDirIndex = index++;
  1863.         myCPB.hFileInfo.ioDirID = theIODirID;
  1864.         
  1865.         errCode = PBGetCatInfo(&myCPB,FALSE);
  1866.         
  1867.         if (errCode!=noErr && errCode!=fnfErr)
  1868.         {
  1869.             sprintf(errorString,"ProcessDirectory:\rPBGetCatInfo error %d",errCode);
  1870.             ErrorAlert(errorString);
  1871.             return(errCode);
  1872.         }
  1873.         
  1874.         else if (errCode == noErr)
  1875.         {
  1876.             PtoCstr(tempString);
  1877.             
  1878.             if (myCPB.hFileInfo.ioFlAttrib & 0x10)
  1879.             {
  1880.                 strcpy(theDirInfo.name,tempString);
  1881.                 theDirInfo.dirID = myCPB.dirInfo.ioDrDirID;
  1882.                 theDirInfo.parentDirID = myCPB.dirInfo.ioDrParID;
  1883.                 theDirInfo.attrib = myCPB.dirInfo.ioFlAttrib;
  1884.                 
  1885.                 for (j=0;j<16;j++)
  1886.                     theDirInfo.finderInfo[j] = ((char *) &(myCPB.dirInfo.ioDrUsrWds))[j];
  1887.                 
  1888.                 for (j=0;j<16;j++)
  1889.                     theDirInfo.finderInfo[j + 16] = ((char *) &(myCPB.dirInfo.ioDrFndrInfo))[j];
  1890.                 
  1891.                 match = FindDir(&theDirInfo);
  1892.                 
  1893.                 if (myCPB.dirInfo.ioDrParID != studentWorkDirID && (match < 0L || CompareDirs(&(listOfDirs[match]),&theDirInfo) != 0))
  1894.                 {
  1895.                     sprintf(errorString,"Moving directory '%s' to %s directory",tempString,STUDENTDIRECTORY);
  1896.                     SetInfoMessage(errorString);
  1897.                     
  1898.                     CtoPstr(tempString);
  1899.                     
  1900.                     myCMovePB.ioCompletion = 0L;
  1901.                     myCMovePB.ioNamePtr = 0L;
  1902.                     myCMovePB.ioVRefNum = vRefNum;
  1903.                     myCMovePB.ioNewName = 0L;
  1904.                     myCMovePB.ioNewDirID = studentWorkDirID;
  1905.                     myCMovePB.ioDirID = myCPB.dirInfo.ioDrDirID;
  1906.                     
  1907.                     errCode = PBCatMove(&myCMovePB,FALSE);
  1908.                     
  1909.                     if (errCode != noErr)
  1910.                     {
  1911.                         PtoCstr(tempString);
  1912.                         sprintf(errorString,"ProcessDirectory:\rPBCatMove(%s) error %d",tempString,errCode);
  1913.                         CtoPstr(tempString);
  1914.                         ErrorAlert(errorString);
  1915.                         errCode = noErr;
  1916.                     }
  1917.                     
  1918.                     else
  1919.                         index--;
  1920.                 }
  1921.             }
  1922.             
  1923.             else
  1924.             {
  1925.                 theFileInfo.type = myCPB.hFileInfo.ioFlFndrInfo.fdType;
  1926.                 theFileInfo.creator = myCPB.hFileInfo.ioFlFndrInfo.fdCreator;
  1927.                 theFileInfo.creationDate = myCPB.hFileInfo.ioFlCrDat;
  1928.                 theFileInfo.parentDirID = myCPB.hFileInfo.ioFlParID;
  1929.                 theFileInfo.attrib = myCPB.hFileInfo.ioFlAttrib;
  1930.                 strcpy(theFileInfo.name,tempString);
  1931.                 
  1932.                 for (j=0;j<16;j++)
  1933.                     theFileInfo.finderInfo[j] = ((char *) &(myCPB.hFileInfo.ioFlFndrInfo))[j];
  1934.                 
  1935.                 for (j=0;j<16;j++)
  1936.                     theFileInfo.finderInfo[j + 16] = ((char *) &(myCPB.hFileInfo.ioFlXFndrInfo))[j];
  1937.                 
  1938.                 match = FindFile(&theFileInfo);
  1939.                 
  1940.                 if (match < 0L && myCPB.hFileInfo.ioFlParID != studentWorkDirID)
  1941.                 {
  1942.                     sprintf(errorString,"Moving file '%s' to %s directory",tempString,STUDENTDIRECTORY);
  1943.                     SetInfoMessage(errorString);
  1944.                     
  1945.                     CtoPstr(tempString);
  1946.                     
  1947.                     myCMovePB.ioCompletion = 0L;
  1948.                     myCMovePB.ioNamePtr = (StringPtr) &tempString;
  1949.                     myCMovePB.ioVRefNum = vRefNum;
  1950.                     myCMovePB.ioNewName = 0L;
  1951.                     myCMovePB.ioNewDirID = studentWorkDirID;
  1952.                     myCMovePB.ioDirID = myCPB.hFileInfo.ioFlParID;
  1953.                     
  1954.                     errCode = PBCatMove(&myCMovePB,FALSE);
  1955.                     
  1956.                     if (errCode != noErr)
  1957.                     {
  1958.                         PtoCstr(tempString);
  1959.                         sprintf(errorString,"ProcessDirectory:\rPBCatMove(%s) error %d",tempString,errCode);
  1960.                         CtoPstr(tempString);
  1961.                         ErrorAlert(errorString);
  1962.                         errCode = noErr;
  1963.                     }
  1964.                     
  1965.                     else
  1966.                         index--;
  1967.                 }
  1968.                 
  1969.                 else
  1970.                 {
  1971.                     sprintf(errorString,"Checking file '%s'",tempString);
  1972.                     SetInfoMessage(errorString);
  1973.                     
  1974.                     CtoPstr(tempString);
  1975.                     
  1976.                     myCPB.hFileInfo.ioCompletion = 0L;
  1977.                     myCPB.hFileInfo.ioNamePtr = (StringPtr) &tempString;
  1978.                     myCPB.hFileInfo.ioVRefNum = vRefNum;
  1979.                     myCPB.hFileInfo.ioFlAttrib = listOfFiles[match].attrib;
  1980.                     myCPB.hFileInfo.ioDirID = myCPB.hFileInfo.ioFlParID;
  1981.                     
  1982.                     for (j=0;j<16;j++)
  1983.                         ((char *) &(myCPB.hFileInfo.ioFlFndrInfo))[j] = listOfFiles[match].finderInfo[j];
  1984.                     
  1985.                     for (j=0;j<16;j++)
  1986.                         ((char *) &(myCPB.hFileInfo.ioFlXFndrInfo))[j] = listOfFiles[match].finderInfo[j + 16];
  1987.                     
  1988.                     errCode = PBSetCatInfo(&myCPB,FALSE);
  1989.                     
  1990.                     PtoCstr(tempString);
  1991.                     
  1992.                     if (errCode != noErr)
  1993.                     {
  1994.                         sprintf(errorString,"ProcessDirectory:\rPBSetCatInfo(%s) error %d",tempString,errCode);
  1995.                         ErrorAlert(errorString);
  1996.                         errCode = noErr;
  1997.                     }
  1998.                     
  1999.                     
  2000.                     if (strcmp(listOfFiles[match].name,theFileInfo.name) != EQSTR)
  2001.                     {
  2002.                         myWDPB.ioCompletion = 0L;
  2003.                         myWDPB.ioNamePtr = 0L;
  2004.                         myWDPB.ioVRefNum = vRefNum;
  2005.                         myWDPB.ioWDProcID = CREATOR;
  2006.                         myWDPB.ioWDDirID = myCPB.hFileInfo.ioFlParID;
  2007.                         
  2008.                         errCode = PBOpenWD(&myWDPB,FALSE);
  2009.                         
  2010.                         if (errCode != noErr)
  2011.                         {
  2012.                             sprintf(errorString,"ProcessDirectory:\rPBOpenWD() error %d",errCode);
  2013.                             ErrorAlert(errorString);
  2014.                             errCode = noErr;
  2015.                         }
  2016.                         
  2017.                         else
  2018.                         {
  2019.                             sprintf(errorString,"Renaming file from '%s' to '%s'",tempString,listOfFiles[match].name);
  2020.                             SetInfoMessage(errorString);
  2021.                             
  2022.                             strcpy(errorString,listOfFiles[match].name);
  2023.                             CtoPstr(errorString);
  2024.                             CtoPstr(tempString);
  2025.                             
  2026.                             myHPB.fileParam.ioCompletion = 0L;
  2027.                             myHPB.fileParam.ioNamePtr = (StringPtr) tempString;
  2028.                             myHPB.fileParam.ioVRefNum = myWDPB.ioVRefNum;
  2029.                             myHPB.ioParam.ioMisc = (Ptr) &errorString;
  2030.                             myHPB.fileParam.ioDirID = 0L;
  2031.                             
  2032.                             errCode = PBHRename(&myHPB,FALSE);
  2033.                             
  2034.                             PtoCstr(tempString);
  2035.                                 
  2036.                             if (errCode != noErr)
  2037.                             {
  2038.                                 sprintf(errorString,"ProcessDirectory:\rPBHRename('%s' -> '%s') error %d",tempString,listOfFiles[match].name,errCode);
  2039.                                 ErrorAlert(errorString);
  2040.                                 errCode = noErr;
  2041.                             }
  2042.                             
  2043.                             else
  2044.                                 strcpy(tempString,listOfFiles[match].name);
  2045.                             
  2046.                             PBCloseWD(&myWDPB,FALSE);
  2047.                         }
  2048.                     }
  2049.                 
  2050.                     if (listOfFiles[match].parentDirID != myCPB.hFileInfo.ioFlParID)
  2051.                     {
  2052.                          sprintf(errorString,"Moving file '%s'",tempString);
  2053.                         CtoPstr(tempString);
  2054.                         SetInfoMessage(errorString);
  2055.                         
  2056.                         myCMovePB.ioCompletion = 0L;
  2057.                         myCMovePB.ioNamePtr = (StringPtr) &tempString;
  2058.                         myCMovePB.ioVRefNum = vRefNum;
  2059.                         myCMovePB.ioNewName = 0L;
  2060.                         myCMovePB.ioNewDirID = listOfFiles[match].parentDirID;
  2061.                         myCMovePB.ioDirID = myCPB.hFileInfo.ioFlParID;
  2062.                         
  2063.                         errCode = PBCatMove(&myCMovePB,FALSE);
  2064.                         
  2065.                         PtoCstr(tempString);
  2066.                         
  2067.                         if (errCode != noErr)
  2068.                         {
  2069.                             sprintf(errorString,"ProcessDirectory:\rPBCatMove(%s) error %d",tempString,errCode);
  2070.                             ErrorAlert(errorString);
  2071.                             errCode = noErr;
  2072.                         }
  2073.                         
  2074.                         else
  2075.                             index--;
  2076.                     }
  2077.                 }
  2078.             }
  2079.         }
  2080.         
  2081.     } while (errCode==noErr);
  2082.     
  2083.     if (errCode == fnfErr)
  2084.         errCode = noErr;
  2085.     
  2086.     
  2087.     
  2088.     if (errCode == noErr)
  2089.     {
  2090.         index = 1;
  2091.             
  2092.         do
  2093.         {
  2094.             tempString[0] = 0;
  2095.             
  2096.             myCPB.hFileInfo.ioCompletion = 0L;
  2097.             myCPB.hFileInfo.ioNamePtr = (StringPtr) &tempString;
  2098.             myCPB.hFileInfo.ioVRefNum = vRefNum;
  2099.             myCPB.hFileInfo.ioFDirIndex = index++;
  2100.             myCPB.hFileInfo.ioDirID = theIODirID;
  2101.             
  2102.             errCode = PBGetCatInfo(&myCPB,FALSE);
  2103.             
  2104.             if (errCode!=noErr && errCode!=fnfErr)
  2105.             {
  2106.                 sprintf(errorString,"ProcessDirectory:\rPBGetCatInfo error %d",errCode);
  2107.                 ErrorAlert(errorString);
  2108.                 return(errCode);
  2109.             }
  2110.             
  2111.             else if (errCode == noErr && myCPB.dirInfo.ioFlAttrib & 0x10 && myCPB.dirInfo.ioDrDirID != studentWorkDirID)
  2112.             {
  2113.                 PtoCstr(tempString);
  2114.                 strcpy(errorString,currentDirName);
  2115.                 strcat(currentDirName,":");
  2116.                 strcat(currentDirName,tempString);
  2117.                 strcpy(tempString,errorString);
  2118.                 
  2119.                 errCode = ProcessDirectory(myCPB.dirInfo.ioDrDirID);
  2120.                 
  2121.                 strcpy(currentDirName,tempString);
  2122.             }
  2123.             
  2124.         } while (errCode==noErr);
  2125.         
  2126.         if (errCode == fnfErr)
  2127.             errCode = noErr;
  2128.     }    
  2129.     
  2130.     FlushVol("\p",vRefNum);
  2131.     
  2132.     return(errCode);
  2133. }
  2134.  
  2135.  
  2136.  
  2137.  
  2138.  
  2139. static int createFolder(char *theFolderName)
  2140. {
  2141. char        tempString[256];
  2142. CInfoPBRec    myCPB;
  2143. int            i,errCode;
  2144.  
  2145.     strcpy(tempString,theFolderName);
  2146.     
  2147.     i = strlen(tempString);
  2148.     if (i > 0 && i < 255 && tempString[i-1] != ':')
  2149.     {
  2150.         tempString[i] = ':';
  2151.         tempString[i+1] = 0;
  2152.     }
  2153.     
  2154.     CtoPstr(tempString);
  2155.     
  2156.     myCPB.hFileInfo.ioCompletion = 0L;
  2157.     myCPB.hFileInfo.ioNamePtr = (StringPtr) &tempString;
  2158.     myCPB.hFileInfo.ioVRefNum = vRefNum;
  2159.     myCPB.hFileInfo.ioFDirIndex = 0L;
  2160.     myCPB.hFileInfo.ioDirID = 0L;
  2161.     
  2162.     errCode = PBDirCreate(&myCPB,FALSE);
  2163.         
  2164.     return(errCode);
  2165. }
  2166.  
  2167.  
  2168.  
  2169.  
  2170.  
  2171.  
  2172. static pascal void HelpScrollProc(ControlHandle theControl,int theCode)
  2173. {
  2174. int            scrollAmt,height;
  2175. int            controlMax,controlMin,controlVal;
  2176. TEHandle    whichTEH;
  2177.  
  2178.     whichTEH = (TEHandle) GetCRefCon(theControl);
  2179.     
  2180.     controlMax = GetCtlMax(theControl);
  2181.     controlMin = GetCtlMin(theControl);
  2182.     controlVal = GetCtlValue(theControl);
  2183.     
  2184.     switch (theCode) 
  2185.     {
  2186.         case inUpButton:
  2187.             if (controlVal > controlMin)
  2188.             {
  2189.                 SetCtlValue(theControl,controlVal-1);
  2190.                 
  2191.                 TEScroll(0,TEGetHeight(controlVal-1,controlVal-1,whichTEH),whichTEH);
  2192.             }
  2193.             
  2194.             break;
  2195.             
  2196.         case inDownButton: 
  2197.             if (controlVal < controlMax)
  2198.             {
  2199.                 SetCtlValue(theControl,controlVal+1);
  2200.                 
  2201.                 TEScroll(0,-TEGetHeight(controlVal,controlVal,whichTEH),whichTEH);
  2202.             }
  2203.             
  2204.             break;
  2205.  
  2206.         case inPageUp: 
  2207.             if (controlVal > controlMin)
  2208.             {
  2209.                 scrollAmt = 1;
  2210.                 height = (**whichTEH).viewRect.bottom - (**whichTEH).viewRect.top;
  2211.                 
  2212.                 while (controlVal-scrollAmt>controlMin && TEGetHeight(controlVal-scrollAmt,controlVal-1,whichTEH)<height)
  2213.                     scrollAmt++;
  2214.                 
  2215.                 if (scrollAmt>1  && TEGetHeight(controlVal-scrollAmt,controlVal-1,whichTEH)>height)
  2216.                     scrollAmt--;
  2217.                 
  2218.                 SetCtlValue(theControl,controlVal-scrollAmt);
  2219.                 
  2220.                 TEScroll(0,TEGetHeight(controlVal-scrollAmt,controlVal-1,whichTEH),whichTEH);
  2221.             }
  2222.             
  2223.             break;
  2224.  
  2225.         case inPageDown: 
  2226.             if (controlVal < controlMax)
  2227.             {
  2228.                 scrollAmt = 1;
  2229.                 height = (**whichTEH).viewRect.bottom - (**whichTEH).viewRect.top;
  2230.                 
  2231.                 while (controlVal+scrollAmt<controlMax && TEGetHeight(controlVal,controlVal+scrollAmt-1,whichTEH)<height)
  2232.                     scrollAmt++;
  2233.                 
  2234.                 if (scrollAmt>1  && TEGetHeight(controlVal,controlVal+scrollAmt-1,whichTEH)>height)
  2235.                     scrollAmt--;
  2236.                 
  2237.                 SetCtlValue(theControl,controlVal+scrollAmt);
  2238.                 
  2239.                 TEScroll(0,-TEGetHeight(controlVal,controlVal+scrollAmt-1,whichTEH),whichTEH);
  2240.             }
  2241.             
  2242.             break;
  2243.     }
  2244. }
  2245.  
  2246.  
  2247.  
  2248. void DoHelpBox(int helpResWIND,int helpResTEXT,int helpResSTYL)
  2249. {
  2250. GrafPtr            oldPort,helpWPtr;
  2251. TEHandle        helpTEH;
  2252. Rect            destRect,viewRect,vScrollRect,doneRect;
  2253. Handle            helpText,helpStyle;
  2254. ControlHandle    vScrollControl,doneControl,whichControl;
  2255. EventRecord        theEvent;
  2256. int                cntlCode,controlVal,oldVal,height;
  2257. char            theChar;
  2258.  
  2259.  
  2260.     GetPort(&oldPort);
  2261.     
  2262.     helpWPtr = GetNewWindow(helpResWIND,0L,(WindowPtr) -1L);
  2263.     SetPort(helpWPtr);
  2264.     
  2265.     CenterWindow(helpWPtr);
  2266.     ShowWindow(helpWPtr);
  2267.     
  2268.     TextFont(geneva);
  2269.     TextSize(10);
  2270.     TextFace(0);
  2271.     
  2272.     SetRect(&viewRect,helpWPtr->portRect.left,helpWPtr->portRect.top,helpWPtr->portRect.right-15,helpWPtr->portRect.bottom-35);
  2273.     InsetRect(&viewRect,5,5);
  2274.     destRect = viewRect;
  2275.     
  2276.     
  2277.     helpTEH = TEStylNew(&destRect,&viewRect);
  2278.     
  2279.     (**helpTEH).lineHeight = -1;
  2280.     (**helpTEH).fontAscent = -1;
  2281.     
  2282.     InsetRect(&viewRect,-5,-5);
  2283.     FrameRect(&viewRect);
  2284.     
  2285.     SetRect(&vScrollRect,viewRect.right-1,viewRect.top,helpWPtr->portRect.right,viewRect.bottom);
  2286.     vScrollControl = NewControl(helpWPtr,&vScrollRect,"\p",TRUE,1,1,1,scrollBarProc,(long) helpTEH);
  2287.     SetRect(&vScrollRect,viewRect.right-1,viewRect.top+16,helpWPtr->portRect.right,viewRect.bottom-16);
  2288.     
  2289.     SetRect(&doneRect,helpWPtr->portRect.right-55,helpWPtr->portRect.bottom-25,helpWPtr->portRect.right-5,helpWPtr->portRect.bottom-5);
  2290.     doneControl = NewControl(helpWPtr,&doneRect,"\pDone",TRUE,0,0,1,pushButProc,0L);
  2291.     
  2292.     PenNormal();
  2293.     PenSize(3,3);
  2294.     InsetRect(&doneRect,-4,-4);
  2295.     FrameRoundRect(&doneRect,16,16);
  2296.     InsetRect(&doneRect,4,4);
  2297.     PenSize(1,1);
  2298.     
  2299.     helpText = GetResource('TEXT',helpResTEXT);
  2300.     helpStyle = GetResource('styl',helpResSTYL);
  2301.     
  2302.     if (helpText!=0L && helpStyle!=0L)
  2303.     {
  2304.         HLock(helpText);
  2305.         
  2306.         TEStylInsert(*helpText,SizeResource(helpText),helpStyle,helpTEH);
  2307.         
  2308.         HUnlock(helpText);
  2309.         ReleaseResource(helpText);
  2310.         ReleaseResource(helpStyle);
  2311.         
  2312.         
  2313.         oldVal = (**helpTEH).nLines;
  2314.         controlVal = 1;
  2315.         height = (**helpTEH).viewRect.bottom - (**helpTEH).viewRect.top;
  2316.         
  2317.         while (oldVal-controlVal>1 && TEGetHeight(oldVal-controlVal,oldVal-1,helpTEH)<height)
  2318.             controlVal++;
  2319.         
  2320.         if (controlVal>1  && TEGetHeight(oldVal-controlVal,oldVal-1,helpTEH)>height)
  2321.             controlVal--;
  2322.         
  2323.         SetCtlMax(vScrollControl,oldVal-controlVal);
  2324.         
  2325.         BeginUpdate(helpWPtr);
  2326.         EndUpdate(helpWPtr);
  2327.         
  2328.         do
  2329.         {
  2330.             SystemTask();
  2331.             
  2332.             cntlCode = 0;
  2333.             
  2334.             if (GetNextEvent(everyEvent,&theEvent))
  2335.             {
  2336.                 if (theEvent.what == mouseDown)
  2337.                 {
  2338.                     GlobalToLocal(&theEvent.where);
  2339.                     
  2340.                     cntlCode = FindControl(theEvent.where,helpWPtr,&whichControl);
  2341.                     
  2342.                     if (cntlCode != 0)
  2343.                     {
  2344.                         if (whichControl == vScrollControl)
  2345.                         {
  2346.                             if (cntlCode == inThumb)
  2347.                             {
  2348.                                 oldVal = GetCtlValue(vScrollControl);
  2349.                                 
  2350.                                 TrackControl(vScrollControl,theEvent.where,0L);
  2351.                                 
  2352.                                 controlVal = GetCtlValue(vScrollControl);
  2353.                                 
  2354.                                 if (controlVal > oldVal)
  2355.                                     TEScroll(0,-TEGetHeight(oldVal,controlVal-1,helpTEH),helpTEH);
  2356.                                     
  2357.                                 else if (controlVal < oldVal)
  2358.                                     TEScroll(0,TEGetHeight(controlVal,oldVal-1,helpTEH),helpTEH);
  2359.                             }
  2360.                             
  2361.                             else
  2362.                                 TrackControl(vScrollControl,theEvent.where,HelpScrollProc);
  2363.                         }
  2364.                         
  2365.                         else if (whichControl == doneControl)
  2366.                             cntlCode = TrackControl(doneControl,theEvent.where,0L);
  2367.                         
  2368.                         else
  2369.                             SysBeep(1);
  2370.                     }
  2371.                     else
  2372.                         SysBeep(1);
  2373.                 }
  2374.                 
  2375.                 else if (theEvent.what==keyDown || theEvent.what==autoKey)
  2376.                 {
  2377.                     theChar = theEvent.message & charCodeMask;
  2378.                     
  2379.                     if (theChar == (char) 0x0d || theChar == (char) 0x03 || theChar == 'd' || theChar == 'D')
  2380.                         cntlCode = inButton;
  2381.                 }
  2382.                 
  2383.                 else if (theEvent.what==updateEvt && (WindowPtr) theEvent.message==helpWPtr)
  2384.                 {
  2385.                     BeginUpdate(helpWPtr);
  2386.                     
  2387.                     DrawControls(helpWPtr);
  2388.                     
  2389.                     if (FrontWindow() != helpWPtr)
  2390.                         EraseRect(&vScrollRect);
  2391.                     else
  2392.                     {
  2393.                         PenNormal();
  2394.                         PenSize(3,3);
  2395.                         InsetRect(&doneRect,-4,-4);
  2396.                         FrameRoundRect(&doneRect,16,16);
  2397.                         InsetRect(&doneRect,4,4);
  2398.                         PenSize(1,1);
  2399.                     }
  2400.                     
  2401.                     TEUpdate(&viewRect,helpTEH);
  2402.                     FrameRect(&viewRect);
  2403.                     
  2404.                     EndUpdate(helpWPtr);
  2405.                 }
  2406.                 
  2407.                 else if (theEvent.message==activateEvt && (WindowPtr) theEvent.message==helpWPtr) 
  2408.                 {
  2409.                     if (theEvent.modifiers & activeFlag) 
  2410.                     {
  2411.                         TEActivate(helpTEH);
  2412.                         HiliteControl(doneControl,0);
  2413.                         
  2414.                         PenNormal();
  2415.                         PenSize(3,3);
  2416.                         InsetRect(&doneRect,-4,-4);
  2417.                         FrameRoundRect(&doneRect,16,16);
  2418.                         InsetRect(&doneRect,4,4);
  2419.                     }
  2420.                     else 
  2421.                     {
  2422.                         TEDeactivate(helpTEH);
  2423.                         EraseRect(&vScrollRect);
  2424.                         
  2425.                         HiliteControl(doneControl,255);
  2426.                         PenNormal();
  2427.                         PenSize(3,3);
  2428.                         PenPat(white);
  2429.                         InsetRect(&doneRect,-4,-4);
  2430.                         FrameRoundRect(&doneRect,16,16);
  2431.                         InsetRect(&doneRect,4,4);
  2432.                     }
  2433.                 }
  2434.             }
  2435.         
  2436.         } while (cntlCode != inButton);
  2437.     }
  2438.     else
  2439.     {
  2440.         SysBeep(1);
  2441.         SysBeep(1);
  2442.         SysBeep(1);
  2443.     }
  2444.     
  2445.     
  2446.     KillControls(helpWPtr);
  2447.     DisposeWindow(helpWPtr);
  2448. }